#include <stdio.h>
#include "main.h"
#include "mem.h"
#include "uart.h"
#include "funcBlock.h"
#include "funcBlock_BUS.h"

struct fb_BUSREDUCT
{
	uint8_t type;
	function_t func;
	uint8_t in[16];
	uint8_t out;
};

struct fb_BUSEXPAND
{
	uint8_t type;
	function_t func;
	uint8_t in;
	uint8_t out[16];
};

void function_fb_BUSEXPAND(struct funcBlock_t *_fb)
{
	uint8_t i;
	struct fb_BUSEXPAND *fb = (struct fb_BUSEXPAND*)_fb;
	uint16_t in = getBusValue_16b(fb->in);
	
	for (i=0; i<16; i++)
	{
		if ((in & (1<<i)) != 0)
			setState(fb->out[i], 1);
		else
			setState(fb->out[i], 0);
	}
}

void function_fb_BUSREDUCT(struct funcBlock_t *_fb)
{
	uint8_t i;
	struct fb_BUSREDUCT *fb = (struct fb_BUSREDUCT*)_fb;
	uint16_t out = 0;
	
	for (i=0; i<16; i++)
	{
		if (getState(fb->in[i]) != 0)
			out |= (1<<i);
	}
	setBusValue_16b(fb->out, out);
}

struct funcBlock_t* get_fb_BUSEXPAND(uint8_t InBus, uint8_t *Out_16x)
{
	struct fb_BUSEXPAND *fb = NULL;
	uint8_t i;

	if ((InBus < NUM_16BIT_BUS) || (InBus == NOT_CONNECTED))
	{	
		fb = (struct fb_BUSEXPAND*)getMem(sizeof(struct fb_BUSEXPAND));
		if (fb != NULL)
		{
			//uart_puts("BUS_EXPAND\n");
			fb->type = FB_TYPE_BUSEXPAND;
			fb->func = function_fb_BUSEXPAND;
			fb->in = InBus;
			for (i=0; i<16; i++)
				fb->out[i] = Out_16x[15-i];
		}
	}
	return (struct funcBlock_t*)fb;
}

struct funcBlock_t* get_fb_BUSREDUCT(uint8_t *In_16x, uint8_t OutBus)
{
	struct fb_BUSREDUCT *fb = NULL;
	uint8_t i;

	if ((OutBus < NUM_16BIT_BUS) || (OutBus == NOT_CONNECTED))
	{	
		fb = (struct fb_BUSREDUCT*)getMem(sizeof(struct fb_BUSREDUCT));
		if (fb != NULL)
		{
			//uart_puts("BUS_REDUCT\n");
			fb->type = FB_TYPE_BUSREDUCT;
			fb->func = function_fb_BUSREDUCT;
			for (i=0; i<16; i++)
				fb->in[i] = In_16x[15-i];
			fb->out = OutBus;
		}
	}
	return (struct funcBlock_t*)fb;
}
